package com.hisense.ovcloud.warehouse.config;

import cn.hutool.json.JSONUtil;
import com.hisense.ovcloud.warehouse.Constants;
import com.hisense.ovcloud.warehouse.tool.FileTool;
import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.audit.AuditManager;
import com.mybatisflex.core.datasource.DataSourceKey;
import com.mybatisflex.core.row.Db;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

import java.util.List;
import java.util.stream.Collectors;

@Configuration
@Order(-1000)
@Slf4j
public class ReadShardingTablesConfig {
    private static final Logger logger = LoggerFactory
            .getLogger("mybatis-flex-sql");

    @Value("${sharding.config.path}")
    private String shardingConfigPath;

    @Value("${spring.flexLogEnable}")
    private boolean mybatisFlexLogEnable;
    public static List<String> domainsList;
    private final FileTool fileTool;

    public ReadShardingTablesConfig(FileTool fileTool) {
        this.fileTool = fileTool;
    }

    private void initSharding(String domainId){
        try{
            DataSourceKey.use(Constants.DS.SHARDING_JDBC);
            Db.selectAll("TABLE_NOT_EXISTED");
        }catch (Exception e){
            log.info("init sharding jdbc.");
        }
        finally{
            DataSourceKey.clear();
        }
    }


    @Bean
    public void fetchDomainsInYaml() {
        if(mybatisFlexLogEnable){
            //开启审计功能
            AuditManager.setAuditEnable(true);

            //设置 SQL 审计收集器
            AuditManager.setMessageCollector(auditMessage ->
                    logger.info("{},{}ms", auditMessage.getFullSql()
                            , auditMessage.getElapsedTime())
            );
        }

        try {
            FlexGlobalConfig.getDefaultConfig()
                    .getDataSource().getDataSourceMap().forEach((k, v) -> {
                        log.info(String.format("datasources config, key: %s , value: %s", k, JSONUtil.toJsonStr(v)));
                    });
            domainsList = fileTool.readFileFromAbsolutePath(shardingConfigPath).stream().filter(s -> s.contains(Constants.JulinkWarehouse.SHARDING_TABLES_PREFIX_IN_YAML) && !s.startsWith("#"))
                    .map(x -> x.strip()
                            .replaceAll(Constants.JulinkWarehouse.SHARDING_TABLES_PREFIX_IN_YAML, "")
                            .replaceAll(":", "")).collect(Collectors.toList());
            domainsList.forEach(this::initSharding);
            log.info("succeed to read domains {} in {}", JSONUtil.toJsonStr(domainsList), shardingConfigPath);
        } catch (Exception e) {
            log.error("Failed to fetch major domains in shardsphereJDBC.yaml! cause: " + e.getMessage());
        }
    }

    public static boolean checkMajorDomain(String domain){
        return domainsList.contains(domain);
    }
}
